if SERVER then

/* ******************************************************************************************************************************** */
/* ********** FUNCTIONS *********************************************************************************************************** */
/* ******************************************************************************************************************************** */

/* Get a team for a player */
function GetTeamForPlayer()

	/* Variables */
	local plyCount				= table.Count( player.GetAll() )
	local attackersTeam			= team.GetInfo( "Attackers" )
	local defendersTeam			= team.GetInfo( "Defenders" )
	local prisonersTeam			= team.GetInfo( "Prisoners" )
	local spectatorsTeam		= team.GetInfo( "Spectators" )
	
	/* If player is alone, give him a random team else than spectators */
	if plyCount == 1 then
		return team.GetGameTeams()[ math.random( 1, 3 ) ]
	end

	/* Check teams status */
	local defendersRatio		= team.NumPlayers( defendersTeam.ID ) / plyCount * 100
	local prisonnersRatio		= team.NumPlayers( prisonersTeam.ID ) / plyCount * 100
	local attackersRatio		= team.NumPlayers( attackersTeam.ID ) / plyCount * 100
	
	/* If a team has too few players, use that one */
	if defendersRatio < defendersTeam.MaxPercent then return defendersTeam end
	if prisonnersRatio < prisonersTeam.MaxPercent then return prisonersTeam end
	if attackersRatio < attackersTeam.MaxPercent then return attackersTeam end
	
	/* Select a random team */
	return team.GetGameTeams()[ math.random( 1, 3 ) ]
end

/* Assign a team to a player */
function SetPlayerTeam( ply, ... )

	/* Variables */
	local plyTeam = nil

	/* Check if a team was given */
	local givenTeam = select(1, ...)
	
	/* If a valid team was given, use it */
	if team.Valid( givenTeam ) then
	
		/* Get team info */
		plyTeam = team.GetInfo( givenTeam )
		
		/* Debug output */
		DEBUG:Msg("Player " .. ply:GetName() .. " will be forced to team '" .. tostring( plyTeam.ChatName ) .. "'", "SetPlayerTeam" )
		
	/* Otherwise, get one */
	else
	
		/* Get a team */
		plyTeam = GetTeamForPlayer()
		
		/* Debug output */
		DEBUG:Msg("No arg team: " .. plyTeam.ChatName, "SetPlayerTeam" )
	end
	
	/* Assign it */
	ply:SetTeam( plyTeam.ID )
end

/* Force a player to respawn */
function ForceRespawn( ply, preserveTeam )

	/* Reset his team if needed */
	if not preserveTeam then SetPlayerTeam( ply ) end
	
	/* Respawn him */
	ply:Spawn()
	
	/* Give loadout */
	GAMEMODE:PlayerLoadout( ply )
end

/* Spawn player on demand */
function SpawnPlayerOnDemand( ply )
	
	/* Spawn them on demand */
	if ply.FirstSpawn and ply:KeyPressed( IN_ATTACK ) or ply:KeyPressed( IN_ATTACK2 ) or ply:KeyPressed( IN_JUMP ) then
	
		/* Debug output */
		DEBUG:Msg( "Player " .. ply:Nick() .. " wants to respawn", "SpawnPlayerOnDemand" )
		
		/* Reset first spawn indicator */
		ply.FirstSpawn = false
		
		/* Spawn him */
		ForceRespawn( ply, false )
	end
end

end